module FSM(sysclk,reset,uartFsmReady,uartFsmData,
	   fsmChrEn,fsmChrData,fsmAluReq,fsmAluOpcode,fsmStackClear,SpyOpc);


input 		sysclk;
input 		reset;
input 		uartFsmReady;
input [7:0] 	uartFsmData;


output reg  [2:0] 	fsmChrEn;
output reg  [7:0] 	fsmChrData;
output reg 				fsmAluReq;
output reg  [2:0]  	fsmAluOpcode;
output reg 				fsmStackClear;
output reg  [3:0] 	SpyOpc;



parameter    	   ENTER = 8'd101,
						MINUS = 8'd45,
						PLUS  = 8'd43,
						MUL   = 8'd42,
						DIVID = 8'd47,
						POINT = 8'd46,
						CHS   = 8'd115,
						CLX   = 8'd120,
						CLR   = 8'd114;


parameter 	INIT = 2'b00,
				HOLD = 2'b01,
				NUM  = 2'b10,
				OPC  = 2'b11;

reg [1:0] state,nextstate;
reg flag;
reg [7:0] FsmData;
reg pointFlag;

always@(posedge sysclk)
	begin
	if(reset)
		begin
		state = HOLD;
		SpyOpc = 4'h0;
		flag 	= 0;
		pointFlag =0;
		end
	else begin
		state =  nextstate;
		flag	=	uartFsmReady;
		end

	case(state)
			HOLD:begin
				if(flag==1)begin
				fsmChrEn  	= 3'b000;
				fsmAluOpcode = 3'b000;
				fsmAluReq 	= 0;
				fsmStackClear 	= 0;
				FsmData			=  uartFsmData;
				flag = 0;                          //I am not sure is this necessary
				if(FsmData>8'd47 && FsmData<8'd58)
					begin
					nextstate	= NUM;
					end
				else begin
					nextstate	= OPC;
						end
					end
				else begin
					fsmChrEn		= 3'b000;
					nextstate	= HOLD;
					fsmAluReq 	= 0;
					end
				end
			NUM: begin
				fsmChrData	= FsmData;
				fsmChrEn	= 3'b001; 
				flag		= 0;
				fsmAluOpcode = 3'b000;
				nextstate	= HOLD;
			     end
			OPC:begin
				case(FsmData)
					ENTER:begin
						fsmChrEn = 3'b010;
						flag 	 = 0;
						nextstate= HOLD;
						SpyOpc= 4'h1;
					      end
					MINUS:begin
						fsmAluReq = 1;
						fsmAluOpcode = 3'b010;
						flag 	  = 0;
						nextstate = HOLD;
						SpyOpc= 4'h2;
					      end
					PLUS :begin
						fsmAluReq = 1;
						fsmAluOpcode = 3'b001;
						flag 	  = 0;
						nextstate = HOLD;
						SpyOpc= 4'h3;
					      end
					DIVID :begin
						fsmAluReq = 1;
						fsmAluOpcode = 3'b011;
						flag 	  = 0;
						nextstate = HOLD;
						SpyOpc= 4'h4;
					      end
					POINT :begin
						fsmAluReq = 1;
						fsmAluOpcode = 3'b000;
						flag 	  = 0;
						nextstate = HOLD;
						pointFlag = 1;
						SpyOpc= 4'h9;
					      end
					MUL :begin
						fsmAluReq = 1;
						fsmAluOpcode = 3'b100;
						flag 	  = 0;
						nextstate = HOLD;
						SpyOpc= 4'h5;
					      end
					CHS :begin
						fsmChrEn  = 3'b011;
						fsmAluOpcode = 3'b000;
						flag 	  = 0;
						nextstate =HOLD;
						SpyOpc= 4'h6;
					     end
					CLX :begin
						fsmChrEn  = 3'b100;
						fsmAluOpcode = 3'b000;
						flag 	  = 0;
						nextstate =HOLD;
						SpyOpc= 4'h7;
					     end
					CLR :begin
						fsmStackClear = 1;
						fsmAluOpcode = 3'b000;
						flag 	  = 0;
						nextstate = HOLD;
						SpyOpc= 4'h8;
						end	
					default:begin
						flag  	  = 0;
						fsmAluOpcode = 3'b000;
						nextstate = HOLD;
						end

				endcase
			end
		endcase
	end
		
endmodule